package org.wdcode.web.upload;

import java.util.List;
import java.util.concurrent.locks.Lock;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import org.wdcode.common.exception.CustomRuntimeException;
import org.wdcode.common.tools.Lists;
import org.wdcode.common.util.CommonUtil;
import org.wdcode.core.concurrent.LockFactory;

/**
 * 上传文件
 * @author WD
 * @since JDK6
 * @version 1.0 2009-03-25
 */
public final class UploadFile {
	// 缩对象
	private final static Lock	LOCK;
	// UploadFile对象
	private static UploadFile	uploadFile;

	// 静态初始化
	static {
		LOCK = LockFactory.getLock();
	}

	/**
	 * 判断是否是multipart表单数据
	 * @param request
	 * @return true false
	 */
	public static boolean isMultiForm(HttpServletRequest request) {
		return ServletFileUpload.isMultipartContent(request);
	}

	/**
	 * 获得实例 newInstance的单例实现
	 * @return UploadFile
	 */
	public static UploadFile getInstance() {
		// 如果uploadFile为空
		if (CommonUtil.isEmpty(uploadFile)) {
			// 锁
			LOCK.lock();
			// 如果uploadFile还是空
			if (CommonUtil.isEmpty(uploadFile)) {
				// 实例化
				uploadFile = newInstance();
			}
			// 解锁
			LOCK.unlock();
		}
		// 返回uploadFile
		return uploadFile;
	}

	/**
	 * 实例化一个新实例
	 * @return UploadFile
	 */
	public static UploadFile newInstance() {
		return new UploadFile();
	}

	/**
	 * 读取上传文件列表
	 * @param request
	 * @return 文件列表
	 */
	public List<FileBean> readFile(HttpServletRequest request) {
		// 声明文件列表
		List<FileBean> lsFile = null;
		// 为该请求创建一个DiskFileItemFactory对象，通过它来解析请求。执行解析后，所有的表单项目都保存在一个List中。
		FileItemFactory factory = new DiskFileItemFactory();
		// 用工厂实例化上传组件
		ServletFileUpload upload = new ServletFileUpload(factory);
		try {
			// 获得上传文件表单列表
			List<?> items = upload.parseRequest(request);
			// 获得列表大小
			int size = items.size();
			// 声明列表 保存文件
			lsFile = Lists.getList(size);
			// 循环列表
			for (int i = 0; i < size; i++) {
				// 获得上传表单实体
				FileItem item = (FileItem) items.get(i);
				// 判断是否是上传文件
				if (!item.isFormField()) {
					// 把文件添加到列表中
					lsFile.add((FileBean) item);
				}
			}
		} catch (Exception e) {
			throw new CustomRuntimeException(e);
		}
		// 返回文件列表
		return lsFile;
	}

	/*
	 * 私有构造
	 */
	private UploadFile() {}
}
